<template>
  <div
    class="container"
    ref="container"
  />
</template>
<script setup lang="ts">
import * as THREE from 'three'
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import * as courses from '@/core/three'
import createGUI from '@/core/gui'
import createStats from '@/core/stats'
import { destroyTHREEModel, THREEModelType } from '@/core/utils'
type nameType = keyof typeof courses

const container = ref<HTMLElement>()
const route = useRoute()
watch([container, route], ([newContainer, newRoute]) => {
  if (!newContainer || newRoute.name !== 'three-course') return
  refresh(newContainer as HTMLElement, newRoute.params.courseId as string)
}, {
  immediate: true
})

onMounted(() => {
  window.addEventListener('resize', onWindowResize, false)
})

onUnmounted(() => {
  window.removeEventListener('resize', onWindowResize, false)
})

let threeModels: THREEModelType
function refresh (dom: HTMLElement, courseId: string) {
  if (threeModels) {
    destroyTHREEModel(threeModels)
  }
  while (dom.hasChildNodes()) {
    dom.removeChild(dom.firstChild!)
  }
  createGUI(container.value!)
  createStats(container.value!)
  const name = `createCourse${courseId}` as nameType
  threeModels = courses[name](dom)
}

function onWindowResize () {
  if (threeModels) {
    const { camera, render } = threeModels
    if (camera instanceof THREE.PerspectiveCamera) {
      camera.aspect = container.value!.offsetWidth / container.value!.offsetHeight
      camera.updateProjectionMatrix()
      render.setSize(container.value!.offsetWidth, container.value!.offsetHeight)
    }
  }
}

</script>
<style lang="scss">
.container{
    height: 100%;
    position: relative;
    .lil-gui.root{
      position: absolute;
      right: 0;
      max-height: 500px;
    }
}
</style>
